<template>
  <div class="app-container">
    <div class="searchBox">
      <el-form :inline="true" :model="search" class="demo-form-inline">
        <el-form-item label="名称：">
          <el-input
            v-model="search.name"
            name="name"
            placeholder="请输入内容"
          />
        </el-form-item>
        <el-form-item label="编码：">
          <el-input
            v-model="search.code"
            name="code"
            placeholder="请输入内容"
          />
        </el-form-item>
        <el-form-item style="margin-top: -2px;">
          <el-button type="primary" @click="searchQuery">查询</el-button>
          <el-button
            type="info"
            @click="
              search = {};
              searchQuery();
            "
          >重置</el-button>
        </el-form-item>
      </el-form>
    </div>

    <qm-table
      ref="qmTable"
      :data="query"
      key-prop="apiId"
      :rules="rules"
      :show-view="false"
      menu-type="text"
      :is-custom-form="true"
      form-refs="form1"
    >
      <qm-table-column field="name" :sortable="true">名称</qm-table-column>
      <qm-table-column field="code" :sortable="true">编码</qm-table-column>
      <qm-table-column field="version" :sortable="true">版本号</qm-table-column>
      <qm-table-column
        field="isCurrent"
        :sortable="true"
        fieldtype="yesno"
      >是否当前版本</qm-table-column>
      <qm-table-column
        field="isEnabled"
        :sortable="true"
        fieldtype="enabledisable"
      >是否启用</qm-table-column>

      <!-- <template #toolbar>
        <el-button type="primary">移动</el-button>
      </template>-->

      <template #moreBtn="{ row }">
        <el-button type="text" @click="preview(row)">预览</el-button>
      </template>
      <template #form="{ controlData, models, defaults }">
        <el-form
          ref="form1"
          :model="models"
          label-width="120px"
          :rules="rules"
          label-suffix=":"
          size="small"
        >
          <div
            style="float: right;z-index: 2; position: relative;padding: 3px;"
          >
            <el-button
              v-if="'apiTable' == tabActive"
              size="small"
              type="primary"
              icon="el-icon-plus"
              @click="addTable(models)"
            >添加数据源</el-button>
            <el-button
              v-if="'apiField' == tabActive"
              size="small"
              type="primary"
              icon="el-icon-plus"
              @click="addField(models, defaults.apiField)"
            >添加字段</el-button>
            <el-dropdown
              v-if="'apiField' == tabActive"
              size="small"
              style="margin-left: 10px"
              @command="
                addTableField($event, models, controlData, defaults.apiField)
              "
            >
              <el-button type="primary" size="small">
                一键添加
                <i class="el-icon-arrow-down el-icon--right" />
              </el-button>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item
                  v-for="item in models.apiTables"
                  :key="item.tableId"
                  :command="item"
                >
                  {{ item.name }}
                </el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
            <el-button
              v-if="'apiFilter' == tabActive"
              size="small"
              type="primary"
              icon="el-icon-plus"
              @click="addFilter(models, defaults.apiFilter)"
            >新增过滤</el-button>
          </div>
          <el-tabs
            v-model="tabActive"
            type="border-card"
            @tab-click="handleTabClick"
          >
            <el-tab-pane label="基本配置" name="apiConfig">
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="名称" prop="model.name">
                    <el-input v-model="models.model.name" />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="编码" prop="model.code">
                    <el-input v-model="models.model.code" />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="版本号" prop="model.version">
                    <el-input v-model="models.model.version" />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="分页查询">
                    <el-select v-model="models.model.pagingType">
                      <el-option
                        v-for="item in controlData.pagingTypeOptions"
                        :key="item.key"
                        :label="item.key"
                        :value="item.value"
                      />
                    </el-select>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-form-item label="设为当前版本">
                    <el-switch v-model="models.model.isCurrent" />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="是否启用">
                    <el-switch v-model="models.model.isEnabled" />
                  </el-form-item>
                </el-col>
                <!--                    <el-col :span="12">-->
                <!--                        <el-form-item label="启用移动端">-->
                <!--                            <el-switch-->
                <!--                                    v-model="models.model.isMobile">-->
                <!--                            </el-switch>-->
                <!--                        </el-form-item>-->
                <!--                    </el-col>-->
              </el-row>
              <!-- <el-row :gutter="20">
                <el-col :span="24">
                  <el-form-item label="代理类" prop="model.baseProxy">
                    <el-input v-model="models.model.baseProxy"></el-input>
                  </el-form-item>
                </el-col>
              </el-row>-->
              <el-row :gutter="20">
                <el-col :span="24">
                  <el-form-item label="默认排序" prop="model.listSort">
                    <el-input v-model="models.model.listSort" />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="20">
                <el-col :span="24">
                  <el-form-item label="全局条件" prop="model.whereFiled">
                    <el-input
                      v-model="models.model.whereFiled"
                      type="textarea"
                      :rows="2"
                      placeholder="全局查询条件"
                    />
                  </el-form-item>
                </el-col>
              </el-row>
            </el-tab-pane>
            <el-tab-pane label="数据源" name="apiTable">
              <el-table
                class="table-no-padding"
                :data="models.apiTables"
                border
                style="width: 100%"
              >
                <el-table-column fixed prop="name" label="名称" width="150" />
                <el-table-column prop="code" label="编码" />
                <el-table-column prop="version" label="版本" width="100" />
                <el-table-column prop="sort" label="顺序" width="100">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.sort" size="small" />
                  </template>
                </el-table-column>
                <el-table-column prop="alias" label="别名">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.alias" size="small" />
                  </template>
                </el-table-column>
                <el-table-column prop="sqlJoinType" label="JOIN关系">
                  <template slot-scope="scope">
                    <el-select v-model="scope.row.sqlJoinType" size="small">
                      <el-option
                        v-for="item in controlData.sqlJoinTypeOptions"
                        :key="item.key"
                        :label="item.key"
                        :value="item.value"
                      />
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column prop="relation" label="ON关系" width="100">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.relation" size="small" />
                  </template>
                </el-table-column>
                <el-table-column fixed="right" label="操作" width="100">
                  <template slot-scope="scope">
                    <el-button
                      type="text"
                      size="small"
                      @click="editTable(scope.row, models)"
                    >管理</el-button>
                    <el-button
                      type="text"
                      size="small"
                      @click="removeTable(scope.row, models)"
                    >移除</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
            <el-tab-pane label="字段查询" name="apiField">
              <el-table
                class="table-no-padding"
                :data="models.apiFields"
                border
                style="width: 100%"
              >
                <el-table-column fixed prop="name" label="名称" width="150">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.name" size="small" />
                  </template>
                </el-table-column>
                <!--                    <el-table-column-->
                <!--                            prop="code"-->
                <!--                            label="编码"-->
                <!--                    >-->
                <!--                        <template slot-scope="scope">-->
                <!--                            <el-input v-model="scope.row.code" size="small"></el-input>-->
                <!--                        </template>-->
                <!--                    </el-table-column>-->
                <el-table-column prop="tableId" label="数据表" width="100">
                  <template slot-scope="scope">
                    <el-select v-model="scope.row.tableId" size="small">
                      <el-option
                        v-for="item in models.apiTables"
                        :key="item.tableId"
                        :label="item.name"
                        :value="item.tableId"
                      />
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column prop="columnId" label="数据列" width="100">
                  <template slot-scope="scope">
                    <el-select v-model="scope.row.columnId" size="small">
                      <el-option
                        v-for="item in getFieldColumn(
                          scope.row.tableId,
                          controlData
                        )"
                        :key="item.columnId"
                        :label="item.name"
                        :value="item.columnId"
                      />
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column prop="fieldSql" label="自定义SQL">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.fieldSql" size="small" />
                  </template>
                </el-table-column>
                <el-table-column prop="alias" label="别名">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.alias" size="small" />
                  </template>
                </el-table-column>
                <el-table-column prop="memo" label="备注">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.memo" size="small" />
                  </template>
                </el-table-column>
                <el-table-column prop="isEnabled" label="启用">
                  <template slot-scope="scope">
                    <el-switch v-model="scope.row.isEnabled" size="small" />
                  </template>
                </el-table-column>
                <el-table-column fixed="right" label="操作" width="100">
                  <template slot-scope="scope">
                    <el-button
                      type="text"
                      size="small"
                      @click="openConvertDialog(scope.row)"
                    >转换</el-button>
                    <el-button
                      type="text"
                      size="small"
                      @click="removeField(scope.row)"
                    >移除</el-button>
                  </template>
                </el-table-column>
              </el-table>

              <vxe-modal
                v-model="dialogFormVisible"
                :resize="true"
                width="1024"
                title="数据转换"
                :show-zoom="true"
                :destroy-on-close="false"
                :show-footer="true"
              >
                <el-form
                  label-width="120px"
                  label-suffix=":"
                  size="small"
                  style="padding: 12px;"
                >
                  <el-form-item label="转换类型">
                    <el-radio-group
                      v-model="dialogField.convertType"
                      size="mini"
                      style="margin-bottom:10px;"
                    >
                      <el-radio-button
                        v-for="item in controlData.convertTypeOptions"
                        :key="item.value"
                        :label="item.value"
                      >{{ item.key }}</el-radio-button>
                    </el-radio-group>
                  </el-form-item>
                  <el-form-item
                    v-if="(dialogField.convertType || '').indexOf('ENUM') > -1"
                    label="枚举类名"
                  >
                    <el-input v-model="dialogField.enumClass" />
                  </el-form-item>
                  <el-form-item
                    v-if="(dialogField.convertType || '').indexOf('DICT') > -1"
                    label="字典类型"
                  >
                    <el-input v-model="dialogField.dictType" />
                  </el-form-item>
                  <!--                        <el-form-item label="字典显示属性" v-if="(dialogField.convertType||'').indexOf('DICT')>-1">-->
                  <!--                            <el-input v-model="dialogField.keyField"></el-input>-->
                  <!--                        </el-form-item>-->
                  <!--                        <el-form-item label="字典值属性" v-if="(dialogField.convertType||'').indexOf('DICT')>-1">-->
                  <!--                            <el-input v-model="dialogField.valueField"></el-input>-->
                  <!--                        </el-form-item>-->

                  <el-form-item
                    v-if="
                      (dialogField.convertType || '').indexOf('OPTION') > -1
                    "
                    label="固定选项"
                  >
                    <el-table
                      class="table-no-padding"
                      :data="dialogFieldOptions"
                      border
                      style="width: 100%"
                    >
                      <el-table-column prop="optionName" label="名称">
                        <template slot-scope="scope">
                          <el-input
                            v-model="scope.row.optionName"
                            size="small"
                          />
                        </template>
                      </el-table-column>
                      <el-table-column prop="optionValue" label="值">
                        <template slot-scope="scope">
                          <el-input
                            v-model="scope.row.optionValue"
                            size="small"
                          />
                        </template>
                      </el-table-column>
                      <el-table-column prop="memo" label="备注">
                        <template slot-scope="scope">
                          <el-input v-model="scope.row.memo" size="small" />
                        </template>
                      </el-table-column>
                      <el-table-column fixed="right" label="操作" width="100">
                        <template slot-scope="scope">
                          <el-button
                            type="text"
                            size="small"
                            @click="removeFieldOption(scope.row, models)"
                          >移除</el-button>
                        </template>
                      </el-table-column>
                    </el-table>
                    <el-button
                      size="small"
                      type="primary"
                      @click="addFieldOption(models, defaults.fieldOption)"
                    >添加</el-button>
                  </el-form-item>
                </el-form>
                <template #footer>
                  <el-row>
                    <el-button
                      size="small"
                      type="danger"
                      @click="clearConvert(models)"
                    >清除</el-button>
                    <el-button
                      size="small"
                      type="primary"
                      @click="dialogFormVisible = false"
                    >确定</el-button>
                  </el-row>
                </template>
              </vxe-modal>
            </el-tab-pane>
            <el-tab-pane label="权限过滤" name="apiFilter">
              <el-table
                class="table-no-padding"
                :data="models.apiFilters"
                border
                style="width: 100%"
              >
                <el-table-column fixed prop="name" label="名称">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.name" size="small" />
                  </template>
                </el-table-column>

                <el-table-column prop="roleId" label="角色" width="150">
                  <template slot-scope="scope">
                    <el-select
                      v-model="scope.row.roleId"
                      value-key="value"
                      filterable
                      remote
                      placeholder="请输入关键词"
                      :remote-method="initRoles"
                      size="small"
                    >
                      <el-option
                        v-for="item in roles"
                        :key="item.value"
                        :label="item.label"
                        :value="item"
                      />
                    </el-select>
                  </template>
                </el-table-column>
                <el-table-column prop="whereSql" label="SQL条件">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.whereSql" size="small" />
                  </template>
                </el-table-column>
                <!--                    <el-table-column-->
                <!--                            prop="columnId"-->
                <!--                            label="过滤类型"-->
                <!--                            width="100">-->
                <!--                        <template slot-scope="scope">-->
                <!--                            <el-select v-model="scope.row.filterType" size="small">-->
                <!--                                <el-option-->
                <!--                                        v-for="item in models.apiTables"-->
                <!--                                        :key="item.key"-->
                <!--                                        :label="item.key"-->
                <!--                                        :value="item.value">-->
                <!--                                </el-option>-->
                <!--                            </el-select>-->
                <!--                        </template>-->
                <!--                    </el-table-column>-->
                <el-table-column prop="memo" label="备注">
                  <template slot-scope="scope">
                    <el-input v-model="scope.row.memo" size="small" />
                  </template>
                </el-table-column>
                <el-table-column prop="isEnabled" label="启用">
                  <template slot-scope="scope">
                    <el-switch v-model="scope.row.isEnabled" size="small" />
                  </template>
                </el-table-column>
                <el-table-column fixed="right" label="操作" width="100">
                  <template slot-scope="scope">
                    <el-button
                      type="text"
                      size="small"
                      @click="removeFilter(scope.row, models)"
                    >移除</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
          </el-tabs>

          <vxe-modal
            v-model="tableModel.visible"
            :show-footer="true"
            fullscreen
            resize
            show-zoom
            width="1024px"
            destroy-on-close
          >
            <smart-table
              ref="smartTable"
              :models="tableModel.models"
              :control-data="tableModel.controlData"
            />

            <template #footer>
              <el-button
                type="primary"
                :loading="tableModel.saveLoading"
                @click="saveTable"
              >保 存</el-button>
            </template>
          </vxe-modal>
        </el-form>
      </template>
    </qm-table>

    <select-table
      v-model="selectTableModalVisible"
      :multiple="true"
      @success="afterSelect"
      @cancel="selectTableModalVisible = false"
    />

    <preview-model
      v-model="previewVisible"
      :title="previewModel.title"
      :url="previewModel.url"
    />
  </div>
</template>

<script>
import Controller from '@/libs/framework/controller'
import SelectTable from '@/views/smartform/smartTable/selectTable'
import SmartTable from '@/views/smartform/smartTable/create'
import PreviewModel from './preview'
import request from '@/utils/request'
import _ from 'lodash'

export default class Instance extends Controller {
  onBeforeInit() {
    this.urls = {
      query: '/smartform/smartApi/query',
      save: '/smartform/smartApi/save',
      delete: '/smartform/smartApi/delete',
      entity: '/smartform/smartApi/getEntity'
    }
  }

  mixin() {
    return {
      components: {
        SelectTable,
        SmartTable,
        PreviewModel
      },
      data() {
        return {
          roles: [],
          tabActive: 'apiConfig',
          rules: {
            'model.name': [
              { required: true, message: '请输入名称', trigger: 'blur' }
            ],
            'model.code': [
              { required: true, message: '请输入编码', trigger: 'blur' }
            ],
            'model.version': [
              { required: true, message: '请输入版本号', trigger: 'blur' }
            ]
          },
          dialogFormVisible: false,
          dialogFieldOptions: [],
          dialogField: {},
          selectTableModalVisible: false,
          previewVisible: false,
          previewModel: {
            title: '',
            url: ''
          },
          tableModel: {
            visible: false,
            models: {},
            controlData: {},
            saveLoading: false
          }
        }
      },
      methods: {
        afterSelect(result) {
          const vm = this.$refs['qmTable'].viewModel
          const formTables = vm.models.formTables
          const apiTables = vm.models.apiTables
          if (result && result.length > 0) {
            let count = apiTables.length + 1
            _.each(result, (table, index) => {
              if (
                _.findIndex(formTables, {
                  tableId: table.tableId
                }) === -1
              ) {
                apiTables.push(
                  _.extend({}, vm.defaults.apiTables, {
                    tableId: table.tableId,
                    name: table.name,
                    code: table.code,
                    version: table.version,
                    sort: count,
                    isCollection: false,
                    isReadOnly: false
                  })
                )
                count++
              }
            })
          }
          this.selectTableModalVisible = false
        },
        addTable(models) {
          this.selectTableModalVisible = true
        },
        editTable(item, models) {
          const loading = this.notifyInfo('数据加载中...')
          request({
            url: '/smartform/smartTable/getEntity',
            method: 'post',
            data: { pageAction: 'edit', tableId: item.tableId }
          }).then(vm => {
            this.tableModel.models = vm.models
            this.tableModel.controlData = vm.controlData
            this.tableModel.visible = true
            loading.close()
          })
        },
        saveTable() {
          this.$refs['smartTable'].$refs['form1'].validate().then(v => {
            if (v) {
              this.tableModel.saveLoading = true
              const postModel = _.extend({}, this.tableModel.models)
              postModel.pageAction = 'edit'
              postModel.tableId = postModel.model.tableId
              request({
                url: '/smartform/smartTable/save',
                method: 'post',
                data: postModel
              }).then(r => {
                if (r && r.success) {
                  this.tableModel.saveLoading = false
                  this.tableModel.visible = false
                  this.notifySuccess('保存成功')
                } else {
                  this.notifyError(r.message || '保存失败')
                }
              })
            }
          })
        },
        removeTable(item, models) {
          models.apiTables.remove(item)
        },
        handleTabClick(tab, event) {
          this.tabActive = tab.name
        },

        addField(models, apiField) {
          models.apiFields.push(_.extend({}, apiField))
        },
        async addTableField(table, models, controlData, apiField) {
          if (table && table.tableId) {
            const loading = this.appLoading('数据加载中...')
            try {
              const columns = await this.getTableField(table.tableId, controlData)
              if (Array.isArray(columns) && columns.length > 0) {
                columns.forEach(item => {
                  if (!_.find(models.apiFields, { columnId: item.columnId })) {
                    models.apiFields.push(
                      _.extend({}, apiField, {
                        code: item.code,
                        columnId: item.columnId,
                        isEnabled: item.isEnabled,
                        isPrimaryKey:
                          item.primaryKeyType === 'PRIMARY_KEY' ||
                          item.primaryKeyType === 'AUTO_PRIMARY_KEY',
                        maxLength: item.dataLength,
                        name: item.name,
                        tableId: item.tableId
                      })
                    )
                  }
                })
              }
            } finally {
              loading.close()
            }
          }
        },
        async getTableField(tableId, controlData) {
          const columns = this.getFieldColumn(tableId, controlData)
          if (columns.length > 0) {
            return columns
          } else {
            const res = await request({
              url: '/smartform/smartTable/getEntity',
              method: 'post',
              data: { tableId: tableId, pageAction: 'edit' }
            })
            return res.models.columns || []
          }
        },
        removeField(item) {
          const vm = this.$refs['qmTable'].viewModel
          vm.models.apiFields.remove(item)
        },

        addFilter(models, apiFilter) {
          models.apiFilters.push(_.extend({}, apiFilter))
        },
        removeFilter(item, models) {
          models.apiFilters.remove(item)
        },
        getFieldColumn(tableId, controlData) {
          return controlData.mapColumns[tableId] || []
        },
        initRoles: function(query) {
          request({
            url: '/admin/sysUser/setRoles/roleSelect2',
            method: 'get',
            params: { term: query }
          }).then(r => {
            this.roles = r.records.map(m => {
              return { value: m.roleId, label: m.name }
            })
          })
        },
        openConvertDialog(row) {
          if (!row.fieldId) {
            this.$message.warning('请先保存表单')
          } else {
            this.dialogField = row
            if (!this.dialogField || !this.dialogField.fieldId) {
              this.dialogFieldOptions = []
            } else {
              const vm = this.$refs['qmTable'].viewModel
              this.dialogFieldOptions =
                vm.models.fieldOptions.filter(o => {
                  return o.fieldId === this.dialogField.fieldId
                }) || []
            }
          }
          this.dialogFormVisible = true
        },
        addFieldOption(models, fieldOption) {
          models.fieldOptions.push(
            _.extend({}, fieldOption, {
              fieldId: this.dialogField.fieldId
            })
          )

          this.dialogFieldOptions = models.fieldOptions.filter(o => {
            return o.fieldId === this.dialogField.fieldId
          })
        },
        removeFieldOption(item, models) {
          models.fieldOptions.remove(item)
        },
        clearConvert(models) {
          var _this = this
          this.$confirm('确定清除该数据转换配置嘛？', '注意').then(function(r) {
            if (r) {
              _this.dialogField.convertType = null
              _this.dialogField.enumClass = null
              _this.dialogField.dictType = null
              const ops = models.fieldOptions.filter(function(p) {
                return p.fieldId === _this.dialogField.fieldId
              })
              if (ops) {
                ops.forEach(function(p) {
                  models.fieldOptions.remove(p)
                })
              }
              _this.$message.success('清除成功')
            }
          })
        },

        preview(row) {
          this.previewModel.title = row.name
          this.previewModel.url = `/smartform/smartApi/previewModel?apiId=${row.apiId}`
          this.previewVisible = true
        }
      }
    }
  }
}
</script>

<style scoped lang="scss"></style>
